package ui

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"x-admin-generator/internal/config"
	"x-admin-generator/internal/database"
	"x-admin-generator/internal/generator"
	"x-admin-generator/internal/types"
	"x-admin-generator/internal/web"
)

// RunInteractiveMode 运行交互式模式
func RunInteractiveMode() {
	fmt.Println("🚀 欢迎使用 X-Admin 代码生成器 (交互式模式)")
	fmt.Println(strings.Repeat("=", 50))

	scanner := bufio.NewScanner(os.Stdin)

	for {
		fmt.Println("\n请选择操作:")
		fmt.Println("1. 生成指定模型的CRUD代码")
		fmt.Println("2. 生成所有模型的CRUD代码")
		fmt.Println("3. 查看现有模型配置")
		fmt.Println("4. 创建新的模型配置")
		fmt.Println("5. 从数据库表生成YAML配置")
		fmt.Println("6. 查看临时目录内容")
		fmt.Println("7. 复制生成的文件到项目")
		fmt.Println("8. 启动Web配置界面")
		fmt.Println("9. 清理临时目录")
		fmt.Println("10. 显示帮助信息")
		fmt.Println("0. 退出")
		fmt.Print("\n请输入选项 (0-10): ")

		if !scanner.Scan() {
			break
		}

		choice := strings.TrimSpace(scanner.Text())

		switch choice {
		case "1":
			HandleGenerateModel(scanner)
		case "2":
			HandleGenerateAllModels()
		case "3":
			HandleListModels()
		case "4":
			HandleCreateModelConfig(scanner)
		case "5":
			HandleGenerateFromDatabase(scanner)
		case "6":
			HandleViewTempDirectory()
		case "7":
			HandleCopyToProject(scanner)
		case "8":
			HandleStartWebServer()
		case "9":
			HandleCleanTempDirectory()
		case "10":
			ShowHelp()
		case "0":
			fmt.Println("👋 感谢使用 X-Admin 代码生成器!")
			return
		default:
			fmt.Println("❌ 无效选项，请输入 0-10 之间的数字")
		}
	}
}

// ShowHelp 显示帮助信息
func ShowHelp() {
	cfg := config.GetConfig()
	fmt.Println("\n📖 X-Admin 代码生成器帮助")
	fmt.Println(strings.Repeat("=", 40))
	fmt.Println("\n命令行用法:")
	fmt.Println("  generator                             启动交互式模式")
	fmt.Println("  generator --interactive               启动交互式模式")
	fmt.Println("  generator generate --model=ModelName  生成指定模型的CRUD代码")
	fmt.Println("  generator generate --all              生成所有模型的CRUD代码")
	fmt.Println("  generator --help                      显示帮助信息")
	fmt.Println("\n示例:")
	fmt.Println("  generator")
	fmt.Println("  generator generate --model=User")
	fmt.Println("  generator generate --all")
	fmt.Println("\n功能说明:")
	fmt.Println("  • 根据YAML配置文件生成完整的CRUD代码")
	fmt.Println("  • 支持后端Go代码和前端Vue代码生成")
	fmt.Println("  • 自动创建模型、服务、处理器和前端页面")
	fmt.Println("  • 支持从数据库表反向生成YAML配置")
	fmt.Printf("  • 配置文件位置: %s/*.yaml\n", cfg.Paths.ModelsConfig)
}

// HandleGenerateModel 处理生成指定模型
func HandleGenerateModel(scanner *bufio.Scanner) {
	fmt.Print("\n请输入模型名称: ")
	if !scanner.Scan() {
		return
	}

	modelName := strings.TrimSpace(scanner.Text())
	if modelName == "" {
		fmt.Println("❌ 模型名称不能为空")
		return
	}

	// 检查配置文件是否存在
	configPath := config.GetConfigPath(fmt.Sprintf("%s.yaml", strings.ToLower(modelName)))
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		fmt.Printf("❌ 配置文件不存在: %s\n", configPath)
		fmt.Print("是否要创建新的配置文件? (y/N): ")
		if scanner.Scan() {
			if strings.ToLower(strings.TrimSpace(scanner.Text())) == "y" {
				CreateModelConfigInteractive(scanner, modelName)
				return
			}
		}
		return
	}

	fmt.Printf("🔄 正在生成模型 %s 的CRUD代码...\n", modelName)
	generator.GenerateModel(modelName)
}

// HandleGenerateAllModels 处理生成所有模型
func HandleGenerateAllModels() {
	fmt.Print("\n确认要生成所有模型的CRUD代码吗? (y/N): ")
	scanner := bufio.NewScanner(os.Stdin)
	if scanner.Scan() {
		if strings.ToLower(strings.TrimSpace(scanner.Text())) == "y" {
			fmt.Println("🔄 正在生成所有模型的CRUD代码...")
			generator.GenerateAllModels()
		} else {
			fmt.Println("❌ 操作已取消")
		}
	}
}

// HandleListModels 处理查看现有模型配置
func HandleListModels() {
	cfg := config.GetConfig()
	configDir := cfg.Paths.ModelsConfig
	files, err := filepath.Glob(filepath.Join(configDir, "*.yaml"))
	if err != nil {
		fmt.Printf("❌ 读取配置目录失败: %v\n", err)
		return
	}

	if len(files) == 0 {
		fmt.Printf("📁 在 %s 目录下没有找到模型配置文件\n", configDir)
		return
	}

	fmt.Println("\n📋 现有模型配置:")
	fmt.Println(strings.Repeat("-", 30))
	for i, file := range files {
		modelName := strings.TrimSuffix(filepath.Base(file), ".yaml")
		fmt.Printf("%d. %s\n", i+1, strings.Title(modelName))
	}
}

// HandleCreateModelConfig 处理创建新的模型配置
func HandleCreateModelConfig(scanner *bufio.Scanner) {
	fmt.Print("\n请输入新模型名称: ")
	if !scanner.Scan() {
		return
	}

	modelName := strings.TrimSpace(scanner.Text())
	if modelName == "" {
		fmt.Println("❌ 模型名称不能为空")
		return
	}

	CreateModelConfigInteractive(scanner, modelName)
}

// HandleGenerateFromDatabase 处理从数据库生成YAML配置
func HandleGenerateFromDatabase(scanner *bufio.Scanner) {
	fmt.Println("\n🗄️  从数据库表生成YAML配置")
	fmt.Println(strings.Repeat("=", 40))

	// 尝试从配置文件读取数据库配置
	dbConfig := config.GetDatabaseConfig()
	if dbConfig == nil {
		cfg := config.GetConfig()
		fmt.Println("📁 未找到配置文件或配置不完整")
		fmt.Println("💡 提示: 请确保以下路径之一存在配置文件:")
		for _, path := range cfg.Database.ConfigPaths {
			fmt.Printf("   - %s\n", path)
		}
		fmt.Println()
		fmt.Println("请手动输入数据库连接信息:")
		dbConfig = database.GetConfigInteractive(scanner)
		if dbConfig == nil {
			return
		}
	} else {
		fmt.Printf("📁 已从配置文件读取数据库配置: %s@%s:%d/%s\n",
			dbConfig.Username, dbConfig.Host, dbConfig.Port, dbConfig.Database)

		// 询问是否使用配置文件中的设置
		fmt.Print("是否使用配置文件中的数据库设置? (Y/n): ")
		if scanner.Scan() {
			response := strings.ToLower(strings.TrimSpace(scanner.Text()))
			if response == "n" || response == "no" {
				fmt.Println("请手动输入数据库连接信息:")
				dbConfig = database.GetConfigInteractive(scanner)
				if dbConfig == nil {
					return
				}
			}
		}
	}

	// 连接数据库
	db, err := database.Connect(dbConfig)
	if err != nil {
		fmt.Printf("❌ 数据库连接失败: %v\n", err)
		return
	}
	defer db.Close()

	// 获取所有表
	tables, err := database.GetTables(db, dbConfig.Database)
	if err != nil {
		fmt.Printf("❌ 获取表列表失败: %v\n", err)
		return
	}

	if len(tables) == 0 {
		fmt.Println("📁 数据库中没有找到表")
		return
	}

	// 显示表列表
	fmt.Println("\n📋 数据库中的表:")
	fmt.Println(strings.Repeat("-", 30))
	for i, table := range tables {
		fmt.Printf("%d. %s", i+1, table.Name)
		if table.Comment != "" {
			fmt.Printf(" (%s)", table.Comment)
		}
		fmt.Println()
	}

	// 选择表
	fmt.Print("\n请选择要生成配置的表 (输入表名或序号，多个用逗号分隔): ")
	if !scanner.Scan() {
		return
	}

	selection := strings.TrimSpace(scanner.Text())
	if selection == "" {
		fmt.Println("❌ 未选择任何表")
		return
	}

	// 解析选择
	selectedTables := database.ParseTableSelection(selection, tables)
	if len(selectedTables) == 0 {
		fmt.Println("❌ 没有找到匹配的表")
		return
	}

	// 为每个选中的表生成配置
	for _, table := range selectedTables {
		fmt.Printf("\n🔄 正在生成表 %s 的配置...\n", table.Name)

		// 获取表的详细信息
		tableInfo, err := database.GetTableInfo(db, dbConfig.Database, table.Name)
		if err != nil {
			fmt.Printf("❌ 获取表信息失败 %s: %v\n", table.Name, err)
			continue
		}

		// 生成模型配置
		modelConfig := GenerateModelConfigFromTable(tableInfo)

		// 保存配置文件
		configPath := config.GetConfigPath(fmt.Sprintf("%s.yaml", strings.ToLower(tableInfo.Name)))
		if err := config.SaveModelConfig(configPath, modelConfig); err != nil {
			fmt.Printf("❌ 保存配置文件失败 %s: %v\n", configPath, err)
			continue
		}

		fmt.Printf("✅ 配置文件已生成: %s\n", configPath)
	}

	fmt.Println("\n✅ 所有选中表的配置文件生成完成!")
	fmt.Println("💡 提示: 生成的配置文件可能需要根据业务需求进行调整")
}

// HandleViewTempDirectory 处理查看临时目录内容
func HandleViewTempDirectory() {
	tempDir := config.GetTempDir()
	if _, err := os.Stat(tempDir); os.IsNotExist(err) {
		fmt.Printf("📁 临时目录不存在: %s\n", tempDir)
		return
	}

	fmt.Printf("\n📁 临时目录内容: %s\n", tempDir)
	fmt.Println(strings.Repeat("-", 40))

	err := filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// 计算相对路径
		relPath, _ := filepath.Rel(tempDir, path)
		if relPath == "." {
			return nil
		}

		// 计算缩进级别
		level := strings.Count(relPath, string(filepath.Separator))
		indent := strings.Repeat("  ", level)

		if info.IsDir() {
			fmt.Printf("%s📁 %s/\n", indent, info.Name())
		} else {
			fmt.Printf("%s📄 %s\n", indent, info.Name())
		}

		return nil
	})

	if err != nil {
		fmt.Printf("❌ 读取目录失败: %v\n", err)
	}
}

// HandleCopyToProject 处理复制生成的文件到项目
func HandleCopyToProject(scanner *bufio.Scanner) {
	tempDir := config.GetTempDir()
	if _, err := os.Stat(tempDir); os.IsNotExist(err) {
		fmt.Printf("📁 临时目录不存在: %s\n", tempDir)
		fmt.Println("💡 请先生成代码，然后再进行复制操作")
		return
	}

	fmt.Println("\n📋 复制生成的文件到项目")
	fmt.Println(strings.Repeat("=", 40))

	// 检查临时目录中是否有文件
	hasFiles, err := CheckTempDirectoryHasFiles(tempDir)
	if err != nil {
		fmt.Printf("❌ 检查临时目录失败: %v\n", err)
		return
	}

	if !hasFiles {
		fmt.Printf("📁 临时目录中没有生成的文件: %s\n", tempDir)
		fmt.Println("💡 请先生成代码，然后再进行复制操作")
		return
	}

	// 显示将要复制的文件
	fmt.Println("📁 将要复制的文件:")
	ShowCopyPreview(tempDir)

	// 确认复制操作
	fmt.Print("\n确认要将生成的文件复制到项目中吗? (y/N): ")
	if !scanner.Scan() {
		return
	}

	if strings.ToLower(strings.TrimSpace(scanner.Text())) != "y" {
		fmt.Println("❌ 操作已取消")
		return
	}

	// 执行复制操作
	if err := CopyGeneratedFilesToProject(tempDir); err != nil {
		fmt.Printf("❌ 复制文件失败: %v\n", err)
		return
	}

	fmt.Println("✅ 文件复制完成!")
	fmt.Println("💡 请检查复制的文件，确保代码正确集成到项目中")
}

// HandleCleanTempDirectory 处理清理临时目录
func HandleCleanTempDirectory() {
	tempDir := config.GetTempDir()
	if _, err := os.Stat(tempDir); os.IsNotExist(err) {
		fmt.Printf("📁 临时目录不存在: %s\n", tempDir)
		return
	}

	fmt.Print("\n确认要清理临时目录吗? 这将删除所有生成的文件 (y/N): ")
	scanner := bufio.NewScanner(os.Stdin)
	if scanner.Scan() {
		if strings.ToLower(strings.TrimSpace(scanner.Text())) == "y" {
			if err := os.RemoveAll(tempDir); err != nil {
				fmt.Printf("❌ 清理临时目录失败: %v\n", err)
			} else {
				fmt.Printf("✅ 临时目录已清理: %s\n", tempDir)
			}
		} else {
			fmt.Println("❌ 操作已取消")
		}
	}
}

// CreateModelConfigInteractive 交互式创建模型配置
func CreateModelConfigInteractive(scanner *bufio.Scanner, modelName string) {
	fmt.Printf("\n🔧 创建模型配置: %s\n", modelName)
	fmt.Println(strings.Repeat("=", 40))

	// 获取表名
	fmt.Printf("请输入表名 (默认: %s): ", strings.ToLower(modelName))
	var tableName string
	if scanner.Scan() {
		tableName = strings.TrimSpace(scanner.Text())
	}
	if tableName == "" {
		tableName = strings.ToLower(modelName)
	}

	// 获取注释
	fmt.Print("请输入模型注释: ")
	var comment string
	if scanner.Scan() {
		comment = strings.TrimSpace(scanner.Text())
	}
	if comment == "" {
		comment = modelName + "管理"
	}

	// 创建基础字段
	fields := []types.Field{
		{Name: "id", Type: "uint", Primary: true, Comment: "主键ID"},
		{Name: "created_at", Type: "time", Comment: "创建时间"},
		{Name: "updated_at", Type: "time", Comment: "更新时间"},
	}

	// 询问是否添加自定义字段
	fmt.Print("\n是否要添加自定义字段? (y/N): ")
	if scanner.Scan() && strings.ToLower(strings.TrimSpace(scanner.Text())) == "y" {
		fields = append(fields, AddCustomFields(scanner)...)
	}

	// 创建配置结构
	modelConfig := types.ModelConfig{
		Model: types.Model{
			Name:    modelName,
			Table:   tableName,
			Comment: comment,
			Fields:  fields,
		},
	}

	// 保存配置文件
	configPath := config.GetConfigPath(fmt.Sprintf("%s.yaml", strings.ToLower(modelName)))
	if err := config.SaveModelConfig(configPath, &modelConfig); err != nil {
		fmt.Printf("❌ 保存配置文件失败: %v\n", err)
		return
	}

	fmt.Printf("✅ 配置文件已创建: %s\n", configPath)

	// 询问是否立即生成代码
	fmt.Print("是否立即生成CRUD代码? (y/N): ")
	if scanner.Scan() && strings.ToLower(strings.TrimSpace(scanner.Text())) == "y" {
		fmt.Printf("🔄 正在生成模型 %s 的CRUD代码...\n", modelName)
		generator.GenerateModel(modelName)
	}
}

// AddCustomFields 添加自定义字段
func AddCustomFields(scanner *bufio.Scanner) []types.Field {
	var fields []types.Field

	fmt.Println("\n📝 添加自定义字段 (输入空行结束):")
	fmt.Println("支持的字段类型: string, int, uint, bool, float64, time")

	for {
		fmt.Print("\n字段名称: ")
		if !scanner.Scan() {
			break
		}

		fieldName := strings.TrimSpace(scanner.Text())
		if fieldName == "" {
			break
		}

		fmt.Print("字段类型 (默认: string): ")
		var fieldType string
		if scanner.Scan() {
			fieldType = strings.TrimSpace(scanner.Text())
		}
		if fieldType == "" {
			fieldType = "string"
		}

		fmt.Print("字段注释: ")
		var comment string
		if scanner.Scan() {
			comment = strings.TrimSpace(scanner.Text())
		}

		fmt.Print("是否必填? (y/N): ")
		var required bool
		if scanner.Scan() {
			required = strings.ToLower(strings.TrimSpace(scanner.Text())) == "y"
		}

		var size int
		if fieldType == "string" {
			fmt.Print("字符串长度 (默认: 255): ")
			if scanner.Scan() {
				if sizeStr := strings.TrimSpace(scanner.Text()); sizeStr != "" {
					if s, err := strconv.Atoi(sizeStr); err == nil {
						size = s
					}
				}
			}
			if size == 0 {
				size = 255
			}
		}

		field := types.Field{
			Name:     fieldName,
			Type:     fieldType,
			Size:     size,
			Required: required,
			Comment:  comment,
		}

		fields = append(fields, field)
		fmt.Printf("✓ 已添加字段: %s (%s)\n", fieldName, fieldType)
	}

	return fields
}

// HandleStartWebServer 启动Web配置界面
func HandleStartWebServer() {
	web.StartWebServer()
}